<?php
/**
 * Created by JetBrains PhpStorm.
 * User: nietao
 * Date: 13-10-17
 * Time: 上午8:53
 * To change this template use File | Settings | File Templates.
 */

namespace Forxx;
use Lavender\Core;


class Redis
{
    private $cache = null;
    private static $instances = array();
    public static $table='';

    //session interface
    // public function set($id, $data, $time)
    // public function update($id, $time)
    // public function delete($id)
    // public function get($id)
    public function __construct($key = null)
    {
        $this->cache = new \Redis;
        if(empty($key)){
            $key = self::$table;
        }
        $config = Core::get_config('cache', $key);
        $config['timeout'] = empty($config['timeout']) ? 1 : $config['timeout'];
        $this->cache->pconnect($config['host'], $config['port'], $config['timeout']);
        if (!empty($config['auth'])) {
            $this->cache->auth($config['auth']);
        }
    }

    public static function instance($key = null)
    {
    	
        // $class = get_called_class();
        // self::$instances='';
        if (!isset(self::$instances[$key])) {
            self::$instances[$key] = new Static($key);
        }
        return self::$instances[$key];
    }

    public function set($id, $data, $time = null)
    {

        $json_value = json_encode($data);
        if($time !== null && is_numeric($time)){
        	return $this->cache->set($id, $json_value, $time);
        }
        
        return $this->cache->set($id, $json_value);
    }
    public function hgetall($id){
        return $this->cache->hgetall($id);
    }

    public function update($id, $data, $time = null)
    {
        $json_value = $this->cache->get($id);
        if ($json_value) {
            $this->cache->del($id);
        }
        $json_value = json_encode($data);
        $this->cache->set($id, $json_value, $time);
    }

    //为兼容之前的代码，故将filed，type赋默认值nil
    public function delete($id, $field = null, $type = null)
    {
        if (is_null($type) && is_null($field)) {
            $this->cache->del($id);
        } else {
            switch ($type) {
                case 'H': // hash表删除
                    return $this->cache->hdel($id, $field);
                //请根据自己的需求扩展
            }
        }
    }

    public function get($id)
    {
        $json_value = $this->cache->get($id);
        if ($json_value) {
            $value = json_decode($json_value, true);
            return $value;
        } else {
            return null;
        }
    }

    //为兼容之前的代码，故将filed，type赋默认值nil
    public function is_exists($key = '', $field = null, $type = null)
    {
        if (is_null($type) && is_null($field)) {
            if (!empty($key)) {
                return $this->cache->exists($key);
            }
        } else {
            switch ($type) {
                case 'H': // hash表检测
                    return $this->cache->hexists($key, $field);
                //请根据自己的需求扩展
            }
        }
        return false;
    }

    //队列操作

    /**
     * 队列入队
     * 返回队列长度
     */

    public function enqueue($key,$value)
    {
        $value = json_encode($value);
        return  $this->cache->RPUSH($key,$value);
    }

    /**
     * 队列出队
     * 返回出队值
     */
    public function dequeue($key)
    {
        $value = $this->cache->LPOP($key);
        return json_decode($value,true);
    }


    /**
     * 队列长度
     */
    public function queue_length($key)
    {
        return $this->cache->LRANGE($key,0,-1);
    }

    /**
     * list类型 左入栈
     * 主要入栈int型数据 如收藏，赞等特性
     * @param $k
     * @param array $v
     */
    public function lpush($k, array $v)
    {
        foreach ($v as $n) {
            $this->cache->lpush($k, $n);

        }
    }

    /**
     * list类型，删除链表类指定的值，返回实际被删除的数量。
     * @param $k
     * @param $v
     * @param int $num
     * @return mixed
     */
    public function lrem($k, $v, $num = 1)
    {
        return $this->cache->lrem($k, $v,$num);
    }

    //list类型 从左至右统计
    public function lrange($k, $offset, $length)
    {
        return $this->cache->lrange($k, $offset, $length);
    }


    /**
     * hash类型
     * 主要存储具对象特性的数据
     * @param $key
     * @param array $arr
     */
    public function hmset($key, array $arr)
    {
        $fileds = array();
        foreach ($arr as $k => $v) {
            $fileds[$k] = serialize($v);
        }
        $this->cache->hmset($key, $fileds);
    }

    /**
     * hash类型
     * 主要用于取hmset的数据
     * @param $key
     * @param array $fields
     * @return mixed
     */
    public function hmget($key, array $fields)
    {
        $res = $this->cache->hmget($key, $fields);
        $result = array();
        foreach ($res as $k => $v) {
            $result[$k] = unserialize($v);
        }
        return $result;
    }
    
    /**
     * Hset
     * wuzhenqiu
     * 
     * @param string $key
     * @param string $field 字段
     * @param array $data 值
     */
    public function hset($key,$field,$data){
    	if(empty($key) || empty($field)){
    		throw new \Exception('param is empty',ErrnoPlus::PARAM_LOSE);
    	}
    	if(is_null($data)){
    		throw new \Exception('value is null',ErrnoPlus::PARAM_INVALID);
    	}
    	$res = $this->cache->hSet($key,$field,json_encode($data));
        return $res;
    }

    /**
     * Hget
     * wuzhenqiu
     * 
     * @param string $key
     * @param string $field 字段
     */
    public function hget($key,$field){
    	if(empty($key) || empty($field)){
    		throw new \Exception('param is empty',ErrnoPlus::PARAM_LOSE);
    	}
    	return json_decode($this->cache->hGet($key,$field),true);
    }

    /**
     * @param string $key
     * @param int $timeout 过期时间 秒
     */
    public function expire($key,$timeout = 86400,$mode = 'NX'){
        return $this->cache->expire($key,$timeout,$mode);
    }
    
}